#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024
#define TOKEN_SIZE 64
#define TOKEN_DELIM " \t"

char *read_input()
{
    printf("> ");

    int buf_size = BUFFER_SIZE;
    char* buf = malloc(buf_size * sizeof(char));
    int c;
    char pos = 0;

    while(1) {
        c = getchar();
        if(c == EOF || c == '\n') {
            buf[pos] = '\0';
            return buf;        
        }
        buf[pos++] = c;
        if(pos >= 1024) {
            buf_size *= 2;
            buf = realloc(buf, buf_size * sizeof(char));
        }
    }
}

char **tokenize(char *input)
{
    int position = 0, buf_size = TOKEN_SIZE;
    char **tokens = malloc(buf_size * sizeof(char*));
    char *token = strtok(input, TOKEN_DELIM);

    while(token != NULL) {
        tokens[position++] = token;
        if(position >= buf_size) {
            buf_size *= 2;
            tokens = realloc(tokens, buf_size * sizeof(char*));
        }
        token = strtok(NULL, TOKEN_DELIM);
    }    
    tokens[position] = '\0';
    return tokens;
}

int execute(char* args)
{
    pid_t pid, wpid;
    int status;

    pid = fork();
    if(pid == 0) {
        //child process;
        if(execvp(args[0], args) == -1) {
            perror("error while executing command in child process");
        }
        exit(0);
    } else if(pid < 0) {
        perror("error while forking");
    } else {
        //master process
        do {        
            wpid = waitpid(pid, &status, WUNTRACED);        
        } while(!WIFEXITED(status) && !WIFSIGNALED(status));
    }
    return 1;
}

int main()
{
    while(1) {
        char *input = read_input();
        
        if(strcmp(input, "exit") == 0) {
            printf("Bye!\n");
            return 0;
        }
        
        char **tokenized = tokenize(input);
        printf("Your command is %s, %lu tokens\n", input, (sizeof(tokenized)/sizeof(tokenized[0])));
        free(input);
        free(tokenized);
    }    
}
